package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.dao.BrandMapper;
import com.qingcheng.dao.SpecMapper;
import com.qingcheng.service.goods.SkuSearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SkuSearchServiceImpl implements SkuSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private SpecMapper specMapper;

    public Map search(Map<String, String> searchMap) throws IOException {
        SearchRequest searchRequest = new SearchRequest("sku");
        searchRequest.types("doc");

        //条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
        MatchQueryBuilder matchQueryBuilder=QueryBuilders.matchQuery("name",searchMap.get("keywords"));

        //分类信息
        if (searchMap.get("category")!=null){
            TermQueryBuilder termQueryBuilder=QueryBuilders.termQuery("categoryName",searchMap.get("category"));
            boolQueryBuilder.filter(termQueryBuilder);
        }

        //分页查询
        if (searchMap.get("pageNo")==null){
            searchMap.put("pageNo","1");
        }
        Integer pageNo =  Integer.parseInt( searchMap.get("pageNo") );//页码
        Integer size =10;
        Integer from=(pageNo-1)*size; //计算分页公式

        searchSourceBuilder.from();
        searchSourceBuilder.size();

        //排序
        String sort = searchMap.get("sort");
        String sortOrder = searchMap.get("sortOrder");
        if (!"".equals(sort)){
            searchSourceBuilder.sort(sort, SortOrder.valueOf(sortOrder));
            //searchSourceBuilder.sort("price", SortOrder.DESC);
        }

        //高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name").preTags("<font style='color:red'>").postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);

        //1.3 品牌过滤
        if (searchMap.get("brand")!=null){
            TermQueryBuilder termQueryBuilder=QueryBuilders.termQuery("brandName",searchMap.get("brand"));
            boolQueryBuilder.filter(termQueryBuilder);
        }

        //1.4 规格过滤
        for (String key:searchMap.keySet()){
            if (key.startsWith("spec.")){ //如果是规格参数
                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key+".keyword", searchMap.get(key));
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }

        //1.5 价格过滤
        if(searchMap.get("price")!=null ){
            String[] price = searchMap.get("price").split("‐");
            if(!price[0].equals("0")){ //最低价格不等于0    
                RangeQueryBuilder rangeQueryBuilder =
                QueryBuilders.rangeQuery("price").gte(price[0] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
            if(!price[1].equals("*")){ //如果价格由上限    
                RangeQueryBuilder rangeQueryBuilder =
                QueryBuilders.rangeQuery("price").lte(price[1] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
        }

        boolQueryBuilder.must(matchQueryBuilder);
        searchSourceBuilder.query(boolQueryBuilder);

        //聚合查询（商品分类） sku_category 自定义 categoryName要分类的字段
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("sku_category").field("categoryName");
        searchSourceBuilder.aggregation(termsAggregationBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //封装结果
        Map resultMap = new HashMap();
        SearchHits hitssearchHits = response.getHits();

        SearchHit[] hits=hitssearchHits.getHits();
        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        for (SearchHit hit:hits){
            Map<String,Object> map=hit.getSourceAsMap();

            //name高亮处理
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Text[] fragments = name.fragments();
            map.put("name",fragments[0].toString());//用高亮的内容替换原内容
            resultList.add(map);
        }
        resultMap.put("rows",resultList);
        //2.2 商品分类列表
        Aggregations aggregations = response.getAggregations();
        Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
        Terms terms = (Terms) aggregationMap.get("sku_category");

        List<? extends Terms.Bucket> buckets =  terms.getBuckets();
        List<String> categoryList=new ArrayList();
        for( Terms.Bucket bucket:buckets ){
            categoryList.add(bucket.getKeyAsString());
        }
        resultMap.put("categoryList",categoryList);

        //分页结果封装
        long totalHits = hitssearchHits.getTotalHits();
        long totalPages=(totalHits%size==0)?totalHits/size:totalHits/size+1;
        resultMap.put("totalPages",totalPages);

        //2.3 品牌列表
        String categoryName="";//商品分类名称
        if(searchMap.get("category")==null){ // 如果没有分类条件
            if(categoryList.size()>0){
                categoryName=categoryList.get(0);//提取分类列表的第一个分类        
            }
        }else{
            categoryName=searchMap.get("category");//取出参数中的分类    
        }
        List<Map> brandList = brandMapper.findListByCategoryName(categoryName);//查询品牌列表
        resultMap.put("brandList",brandList);

        //2.4 规格列表
        List<Map> specList = specMapper.findListByCategoryName(categoryName);//规格列表
        for(Map spec:specList){
            String[] options = ((String) spec.get("options")).split(",");//规格选项列表
            spec.put("options",options);
        }
        resultMap.put("specList",specList);
        return resultMap;
    }
}
